<template>
    <view class="markdown-render">
        <template v-for="(node, index) in nodes" :key="index">
            <!-- 普通文本 -->
            <view v-if="node.type === 'text'" v-html="node.content"></view>

            <!-- think 块 -->
            <view v-else-if="node.type === 'think'" class="think-box">{{ node.content }}</view>

            <!-- 自定义按钮 -->
            <button v-else-if="node.type === 'button'" class="btn" :class="node.btnType"
                @click="handleClick(node.clickFn)">
                {{ node.content }}
            </button>
            <!-- 代码块 -->
            <view v-else-if="node.type === 'code'" class="code-block">
                <!-- #ifdef H5 -->
                <pre v-html="node.content"></pre>
                <view class="copy-btn" @click="copyCode(node.raw)">复制代码</view>
                <!-- #endif -->

                <!-- #ifndef H5 -->
                <view class="mini-code">
                    <view selectable="true" v-html="node.content"></view>
                </view>
                <view class="copy-btn" @click="copyCode(node.raw)">复制代码</view>
                <!-- #endif -->
            </view>

        </template>
    </view>
</template>

<script setup>
import { ref, watch } from 'vue'
import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
const props=defineProps({
    content: String,
    buttonClickMap: {
        type: Object,
        default: () => ({})
    }
})
const nodes=ref([])
const md=new MarkdownIt({ html: true, linkify: true })

// 解析 Markdown + 自定义 think/button/代码块
function parseMarkdown (content) {
    const result=[]
    let remaining=content

    // 处理 think/button/code 三种特殊块
    const regex=/:::think([\s\S]+?):::|:::button\s+text="([\s\S]+?)"\s+type="([\s\S]+?)"\s+click="([\s\S]+?)"\s*:::|```([\s\S]+?)```/g
    let lastIndex=0
    let match

    while((match=regex.exec(content))!==null) {
        // 普通文本
        if(match.index>lastIndex) {
            const textPart=content.slice(lastIndex, match.index).trim()
            if(textPart) result.push({ type: 'text', content: md.render(textPart) })
        }

        if(match[1]) {
            // think 块
            result.push({ type: 'think', content: match[1].trim() })
        } else if(match[2]) {
            // button 块
            result.push({
                type: 'button',
                content: match[2].trim(),
                btnType: match[3].trim(),
                clickFn: match[4].trim()
            })
        } else if(match[5]) {
            // 代码块
            const codeContent=match[5].trim()
            const highlighted=hljs.highlightAuto(codeContent).value
            result.push({ type: 'code', content: highlighted, raw: codeContent })
        }

        lastIndex=regex.lastIndex
    }

    // 剩余文本
    if(lastIndex<content.length) {
        const textPart=content.slice(lastIndex).trim()
        if(textPart) result.push({ type: 'text', content: md.render(textPart) })
    }

    return result
}

watch(() => props.content, val => {
    nodes.value=parseMarkdown(val)
}, { immediate: true })

function handleClick (fnName) {
    if(props.buttonClickMap[fnName]) props.buttonClickMap[fnName]()
}

// 复制代码
function copyCode (code) {
    if(typeof navigator!=='undefined'&&navigator.clipboard) {
        navigator.clipboard.writeText(code).then(() => {
            uni.showToast({ title: '复制成功', icon: 'success' })
        })
    } else {
        // 小程序 uni.setClipboardData
        uni.setClipboardData({
            data: code,
            success () { uni.showToast({ title: '复制成功', icon: 'success' }) }
        })
    }
}
</script>

<style scoped lang="scss">
.markdown-render {
    max-width: calc(100vw - 80rpx);
    font-size: 14px;
    line-height: 1.6;
    color: #333;
    margin: 0 auto;
    margin-left: 20rpx;
    margin-top: 5px;
    /* 避免整体撑爆父级 */
    overflow-x: hidden;
    /* 禁止整体出现横向滚动条 */
    word-wrap: break-word;
    /* 普通文本自动换行 */
    padding: 10px;
    background-color: #f5f5f5;
    box-sizing: border-box;
    border-radius: 18rpx;
}

/* think 块 */
.think-box {
    border-left: 3px solid #00d2ca;
    padding: 10px;
    background: #f0f9f9;
    margin: 10px 0;
    word-wrap: break-word;
}

/* 自定义按钮 */
.btn {
    margin: 5px 0;
    padding: 6px 12px;
    border-radius: 4px;
    font-size: 14px;
    color: #fff;
    cursor: pointer;
}

.btn.primary {
    background-color: #00d2ca;
}

.btn.success {
    background-color: #28a745;
}

.btn.warning {
    background-color: #ffc107;
}

.btn.danger {
    background-color: #dc3545;
}

/* 代码块容器 */
.code-block {
    position: relative;
    margin: 12px 0;
    width: calc(100vw - 120rpx);
    overflow-x: auto;

    pre,
    code {
        font-family: monospace;
        background-color: #e6e1e1;
        padding: 10px;
        border-radius: 8px;
        overflow-x: auto;
        white-space: pre-wrap;
        word-break: break-word;
    }


    .mini-code {
        background: #2d2d2d;
        color: #f8f8f2;
        font-family: monospace;
        font-size: 14px;
        padding: 10px;
        border-radius: 8px;
        white-space: pre-wrap;
        word-break: break-word;
    }

}


/* 复制按钮 */
.copy-btn {
    position: absolute;
    top: 5px;
    right: 5px;
    padding: 2px 6px;
    border: none;
    background: #00d2ca;
    color: #fff;
    border-radius: 3px;
    cursor: pointer;
}
</style>
